#include <vector>
#include <iomanip> 
#include <chrono>
#include "matrix_operations_gpu.cu"
#include "matrix_operations_cpu.h"
#include "simple_fnn.cpp"
#include "relu.h"


// 生成一个指定大小和随机小数填充的矩阵
std::vector<std::vector<double>> generateRandomMatrix(int cols, int rows, double min = 0.0, double max = 1.0) {
    std::vector<std::vector<double>> matrix(rows, std::vector<double>(cols));

    // 用来生成随机数的设备
    std::random_device rd;
    // 随机数生成器
    std::mt19937 gen(rd());
    // 定义一个分布，这里使用[min, max)区间的均匀分布
    std::uniform_real_distribution<> dis(min, max);

    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            // 为矩阵的每个元素赋予一个随机生成的小数
            matrix[i][j] = dis(gen);
        }
    }
    
    return matrix;
}

// 函数用来打印矩阵
void printMatrix(const std::vector<std::vector<double>>& matrix) {
    for (const auto& row : matrix) {
        for (const auto& val : row) {
            std::cout << std::fixed << std::setprecision(6) << std::setw(10) << val << " ";
        }
        std::cout << std::endl;
    }
}



int main() {
    auto start = std::chrono::high_resolution_clock::now();
    // GPU
    // 定义网络结构
    FNN network(2, 1024, 1024, 2, 0.01, std::make_shared<ReLU>(), std::make_shared<MatrixOperationsGPU>());
    //CPU
    //FNN network(2, 1024, 1024, 2, 0.01, std::make_shared<ReLU>(), std::make_shared<MatrixOperationsCPU>());
    // 测试数据集
    std::vector<std::vector<double>> testData = generateRandomMatrix(2, 10000);
    for (const auto& sample : testData) {
        auto output = network.predict({sample}); // 假设predict函数正如之前所描述

        // 输出矩阵格式，现在使用固定小数点格式和相同宽度保证对齐
        // for (const auto& row : output) {
        //     for (const auto& value : row) {
        //         std::cout << std::fixed << std::setprecision(6) // 固定显示6位小数
        //                 << std::setw(10) << value << " "; // 设置宽度保证对齐，包括小数点和小数部分
        //     }
        //     std::cout << std::endl; // 每行输出后换行
        // }
    }
    auto stop = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);

    std::cout << "Time taken by function: " << duration.count() << " milliseconds" << std::endl;
    fflush(stdout);
    return 0;
}
